home *** CD-ROM | disk | FTP | other *** search
- Path: abcfd20.larc.nasa.gov!amiga-request
- From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v90i229: flex 2.3 - fast lexical analyzer generator, Part02/13
- Reply-To: loftus@wpllabs.uucp (William P Loftus)
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v90i229@abcfd20.larc.nasa.gov>
- Date: 19 Aug 90 22:42:05 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: loftus@wpllabs.uucp (William P Loftus)
- Posting-number: Volume 90, Issue 229
- Archive-name: unix/flex-2.3/part02
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 13)."
- # Contents: Changes misc.c parse.y scan.l
- # Wrapped by tadguy@abcfd20 on Sun Aug 19 18:41:42 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Changes' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Changes'\"
- else
- echo shar: Extracting \"'Changes'\" \(11046 characters\)
- sed "s/^X//" >'Changes' <<'END_OF_FILE'
- XChanges between 2.3 (full) release of 28Jun90 and 2.2 (alpha) release:
- X
- X User-visible:
- X
- X - A lone <<EOF>> rule (that is, one which is not qualified with
- X a list of start conditions) now specifies the EOF action for
- X *all* start conditions which haven't already had <<EOF>> actions
- X given. To specify an end-of-file action for just the initial
- X state, use <INITIAL><<EOF>>.
- X
- X - -d debug output is now contigent on the global yy_flex_debug
- X being set to a non-zero value, which it is by default.
- X
- X - A new macro, YY_USER_INIT, is provided for the user to specify
- X initialization action to be taken on the first call to the
- X scanner. This action is done before the scanner does its
- X own initialization.
- X
- X - yy_new_buffer() has been added as an alias for yy_create_buffer()
- X
- X - Comments beginning with '#' and extending to the end of the line
- X now work, but have been deprecated (in anticipation of making
- X flex recognize #line directives).
- X
- X - The funky restrictions on when semi-colons could follow the
- X YY_NEW_FILE and yyless macros have been removed. They now
- X behave identically to functions.
- X
- X - A bug in the sample redefinition of YY_INPUT in the documentation
- X has been corrected.
- X
- X - A bug in the sample simple tokener in the documentation has
- X been corrected.
- X
- X - The documentation on the incompatibilities between flex and
- X lex has been reordered so that the discussion of yylineno
- X and input() come first, as it's anticipated that these will
- X be the most common source of headaches.
- X
- X
- X Things which didn't used to be documented but now are:
- X
- X - flex interprets "^foo|bar" differently from lex. flex interprets
- X it as "match either a 'foo' or a 'bar', providing it comes at the
- X beginning of a line", whereas lex interprets it as "match either
- X a 'foo' at the beginning of a line, or a 'bar' anywhere".
- X
- X - flex initializes the global "yyin" on the first call to the
- X scanner, while lex initializes it at compile-time.
- X
- X - yy_switch_to_buffer() can be used in the yywrap() macro/routine.
- X
- X - flex scanners do not use stdio for their input, and hence when
- X writing an interactive scanner one must explictly call fflush()
- X after writing out a prompt.
- X
- X - flex scanner can be made reentrant (after a fashion) by using
- X "yyrestart( yyin );". This is useful for interactive scanners
- X which have interrupt handlers that long-jump out of the scanner.
- X
- X - a defense of why yylineno is not supported is included, along
- X with a suggestion on how to convert scanners which rely on it.
- X
- X
- X Other changes:
- X
- X - Prototypes and proper declarations of void routines have
- X been added to the flex source code, courtesy of Kevin B. Kenny.
- X
- X - Routines dealing with memory allocation now use void* pointers
- X instead of char* - see Makefile for porting implications.
- X
- X - Error-checking is now done when flex closes a file.
- X
- X - Various lint tweaks were added to reduce the number of gripes.
- X
- X - Makefile has been further parameterized to aid in porting.
- X
- X - Support for SCO Unix added.
- X
- X - Flex now sports the latest & greatest UC copyright notice
- X (which is only slightly different from the previous one).
- X
- X - A note has been added to flexdoc.1 mentioning work in progress
- X on modifying flex to generate straight C code rather than a
- X table-driven automaton, with an email address of whom to contact
- X if you are working along similar lines.
- X
- X
- XChanges between 2.2 Patch #3 (30Mar90) and 2.2 Patch #2:
- X
- X - fixed bug which caused -I scanners to bomb
- X
- X
- XChanges between 2.2 Patch #2 (27Mar90) and 2.2 Patch #1:
- X
- X - fixed bug writing past end of input buffer in yyunput()
- X - fixed bug detecting NUL's at the end of a buffer
- X
- X
- XChanges between 2.2 Patch #1 (23Mar90) and 2.2 (alpha) release:
- X
- X - Makefile fixes: definition of MAKE variable for systems
- X which don't have it; installation of flexdoc.1 along with
- X flex.1; fixed two bugs which could cause "bigtest" to fail.
- X
- X - flex.skel fix for compiling with g++.
- X
- X - README and flexdoc.1 no longer list an out-of-date BITNET address
- X for contacting me.
- X
- X - minor typos and formatting changes to flex.1 and flexdoc.1.
- X
- X
- XChanges between 2.2 (alpha) release of March '90 and previous release:
- X
- X User-visible:
- X
- X - Full user documentation now available.
- X
- X - Support for 8-bit scanners.
- X
- X - Scanners now accept NUL's.
- X
- X - A facility has been added for dealing with multiple
- X input buffers.
- X
- X - Two manual entries now. One which fully describes flex
- X (rather than just its differences from lex), and the
- X other for quick(er) reference.
- X
- X - A number of changes to bring flex closer into compliance
- X with the latest POSIX lex draft:
- X
- X %t support
- X flex now accepts multiple input files and concatenates
- X them together to form its input
- X previous -c (compress) flag renamed -C
- X do-nothing -c and -n flags added
- X Any indented code or code within %{}'s in section 2 is
- X now copied to the output
- X
- X - yyleng is now a bona fide global integer.
- X
- X - -d debug information now gives the line number of the
- X matched rule instead of which number rule it was from
- X the beginning of the file.
- X
- X - -v output now includes a summary of the flags used to generate
- X the scanner.
- X
- X - unput() and yyrestart() are now globally callable.
- X
- X - yyrestart() no longer closes the previous value of yyin.
- X
- X - C++ support; generated scanners can be compiled with C++ compiler.
- X
- X - Primitive -lfl library added, containing default main()
- X which calls yylex(). A number of routines currently living
- X in the scanner skeleton will probably migrate to here
- X in the future (in particular, yywrap() will probably cease
- X to be a macro and instead be a function in the -lfl library).
- X
- X - Hexadecimal (\x) escape sequences added.
- X
- X - Support for MS-DOS, VMS, and Turbo-C integrated.
- X
- X - The %used/%unused operators have been deprecated. They
- X may go away soon.
- X
- X
- X Other changes:
- X
- X - Makefile enhanced for easier testing and installation.
- X - The parser has been tweaked to detect some erroneous
- X constructions which previously were missed.
- X - Scanner input buffer overflow is now detected.
- X - Bugs with missing "const" declarations fixed.
- X - Out-of-date Minix/Atari patches provided.
- X - Scanners no longer require printf() unless FLEX_DEBUG is being used.
- X - A subtle input() bug has been fixed.
- X - Line numbers for "continued action" rules (those following
- X the special '|' action) are now correct.
- X - unput() bug fixed; had been causing problems porting flex to VMS.
- X - yymore() handling rewritten to fix bug with interaction
- X between yymore() and trailing context.
- X - EOF in actions now generates an error message.
- X - Bug involving -CFe and generating equivalence classes fixed.
- X - Bug which made -CF be treated as -Cf fixed.
- X - Support for SysV tmpnam() added.
- X - Unused #define's for scanner no longer generated.
- X - Error messages which are associated with a particular input
- X line are now all identified with their input line in standard
- X format.
- X - % directives which are valid to lex but not to flex are
- X now ignored instead of generating warnings.
- X - -DSYS_V flag can now also be specified -DUSG for System V
- X compilation.
- X
- X
- XChanges between 2.1 beta-test release of June '89 and previous release:
- X
- X User-visible:
- X
- X - -p flag generates a performance report to stderr. The report
- X consists of comments regarding features of the scanner rules
- X which result in slower scanners.
- X
- X - -b flag generates backtracking information to lex.backtrack.
- X This is a list of scanner states which require backtracking
- X and the characters on which they do so. By adding rules
- X one can remove backtracking states. If all backtracking states
- X are eliminated, the generated scanner will run faster.
- X Backtracking is not yet documented in the manual entry.
- X
- X - Variable trailing context now works, i.e., one can have
- X rules like "(foo)*/[ \t]*bletch". Some trailing context
- X patterns still cannot be properly matched and generate
- X error messages. These are patterns where the ending of the
- X first part of the rule matches the beginning of the second
- X part, such as "zx*/xy*", where the 'x*' matches the 'x' at
- X the beginning of the trailing context. Lex won't get these
- X patterns right either.
- X
- X - Faster scanners.
- X
- X - End-of-file rules. The special rule "<<EOF>>" indicates
- X actions which are to be taken when an end-of-file is
- X encountered and yywrap() returns non-zero (i.e., indicates
- X no further files to process). See manual entry for example.
- X
- X - The -r (reject used) flag is gone. flex now scans the input
- X for occurrences of the string "REJECT" to determine if the
- X action is needed. It tries to be intelligent about this but
- X can be fooled. One can force the presence or absence of
- X REJECT by adding a line in the first section of the form
- X "%used REJECT" or "%unused REJECT".
- X
- X - yymore() has been implemented. Similarly to REJECT, flex
- X detects the use of yymore(), which can be overridden using
- X "%used" or "%unused".
- X
- X - Patterns like "x{0,3}" now work (i.e., with lower-limit == 0).
- X
- X - Removed '\^x' for ctrl-x misfeature.
- X
- X - Added '\a' and '\v' escape sequences.
- X
- X - \<digits> now works for octal escape sequences; previously
- X \0<digits> was required.
- X
- X - Better error reporting; line numbers are associated with rules.
- X
- X - yyleng is a macro; it cannot be accessed outside of the
- X scanner source file.
- X
- X - yytext and yyleng should not be modified within a flex action.
- X
- X - Generated scanners #define the name FLEX_SCANNER.
- X
- X - Rules are internally separated by YY_BREAK in lex.yy.c rather
- X than break, to allow redefinition.
- X
- X - The macro YY_USER_ACTION can be redefined to provide an action
- X which is always executed prior to the matched rule's action.
- X
- X - yyrestart() is a new action which can be used to restart
- X the scanner after it has seen an end-of-file (a "real" one,
- X that is, one for which yywrap() returned non-zero). It takes
- X a FILE* argument indicating a new file to scan and sets
- X things up so that a subsequent call to yylex() will start
- X scanning that file.
- X
- X - Internal scanner names all preceded by "yy_"
- X
- X - lex.yy.c is deleted if errors are encountered during processing.
- X
- X - Comments may be put in the first section of the input by preceding
- X them with '#'.
- X
- X
- X
- X Other changes:
- X
- X - Some portability-related bugs fixed, in particular for machines
- X with unsigned characters or sizeof( int* ) != sizeof( int ).
- X Also, tweaks for VMS and Microsoft C (MS-DOS), and identifiers all
- X trimmed to be 31 or fewer characters. Shortened file names
- X for dinosaur OS's. Checks for allocating > 64K memory
- X on 16 bit'ers. Amiga tweaks. Compiles using gcc on a Sun-3.
- X - Compressed and fast scanner skeletons merged.
- X - Skeleton header files done away with.
- X - Generated scanner uses prototypes and "const" for __STDC__.
- X - -DSV flag is now -DSYS_V for System V compilation.
- X - Removed all references to FTL language.
- X - Software now covered by BSD Copyright.
- X - flex will replace lex in subsequent BSD releases.
- END_OF_FILE
- if test 11046 -ne `wc -c <'Changes'`; then
- echo shar: \"'Changes'\" unpacked with wrong size!
- fi
- # end of 'Changes'
- fi
- if test -f 'misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc.c'\"
- else
- echo shar: Extracting \"'misc.c'\" \(14248 characters\)
- sed "s/^X//" >'misc.c' <<'END_OF_FILE'
- X/* misc - miscellaneous flex routines */
- X
- X/*-
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Vern Paxson.
- X *
- X * The United States Government has rights in this work pursuant
- X * to contract no. DE-AC03-76SF00098 between the United States
- X * Department of Energy and the University of California.
- X *
- X * Redistribution and use in source and binary forms are permitted provided
- X * that: (1) source distributions retain this entire copyright notice and
- X * comment, and (2) distributions including binaries display the following
- X * acknowledgement: ``This product includes software developed by the
- X * University of California, Berkeley and its contributors'' in the
- X * documentation or other materials provided with the distribution and in
- X * all advertising materials mentioning features or use of this software.
- X * Neither the name of the University nor the names of its contributors may
- X * be used to endorse or promote products derived from this software without
- X * specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xstatic char rcsid[] =
- X "@(#) $Header: WPL:Generators/flex-2.3/RCS/misc.c,v 1.2 90/07/15 01:18:35 loftus Exp $ (LBL)";
- X#endif
- X
- X#include <ctype.h>
- X#include "flexdef.h"
- X
- X
- X/* ANSI C does not guarantee that isascii() is defined */
- X#ifndef isascii
- X#define isascii(c) ((c) <= 0177)
- X#endif
- X
- X
- X
- X/* declare functions that have forward references */
- X
- Xvoid dataflush PROTO(());
- Xint otoi PROTO((Char []));
- X
- X
- X/* action_out - write the actions from the temporary file to lex.yy.c
- X *
- X * synopsis
- X * action_out();
- X *
- X * Copies the action file up to %% (or end-of-file) to lex.yy.c
- X */
- X
- Xvoid action_out()
- X
- X {
- X char buf[MAXLINE];
- X
- X while ( fgets( buf, MAXLINE, temp_action_file ) != NULL )
- X if ( buf[0] == '%' && buf[1] == '%' )
- X break;
- X else
- X fputs( buf, stdout );
- X }
- X
- X
- X/* allocate_array - allocate memory for an integer array of the given size */
- X
- Xvoid *allocate_array( size, element_size )
- Xint size, element_size;
- X
- X {
- X register void *mem;
- X
- X /* on 16-bit int machines (e.g., 80286) we might be trying to
- X * allocate more than a signed int can hold, and that won't
- X * work. Cheap test:
- X */
- X if ( element_size * size <= 0 )
- X flexfatal( "request for < 1 byte in allocate_array()" );
- X
- X mem = (void *) malloc( (unsigned) (element_size * size) );
- X
- X if ( mem == NULL )
- X flexfatal( "memory allocation failed in allocate_array()" );
- X
- X return ( mem );
- X }
- X
- X
- X/* all_lower - true if a string is all lower-case
- X *
- X * synopsis:
- X * Char *str;
- X * int all_lower();
- X * true/false = all_lower( str );
- X */
- X
- Xint all_lower( str )
- Xregister Char *str;
- X
- X {
- X while ( *str )
- X {
- X if ( ! isascii( *str ) || ! islower( *str ) )
- X return ( 0 );
- X ++str;
- X }
- X
- X return ( 1 );
- X }
- X
- X
- X/* all_upper - true if a string is all upper-case
- X *
- X * synopsis:
- X * Char *str;
- X * int all_upper();
- X * true/false = all_upper( str );
- X */
- X
- Xint all_upper( str )
- Xregister Char *str;
- X
- X {
- X while ( *str )
- X {
- X if ( ! isascii( *str ) || ! isupper( (char) *str ) )
- X return ( 0 );
- X ++str;
- X }
- X
- X return ( 1 );
- X }
- X
- X
- X/* bubble - bubble sort an integer array in increasing order
- X *
- X * synopsis
- X * int v[n], n;
- X * bubble( v, n );
- X *
- X * description
- X * sorts the first n elements of array v and replaces them in
- X * increasing order.
- X *
- X * passed
- X * v - the array to be sorted
- X * n - the number of elements of 'v' to be sorted */
- X
- Xvoid bubble( v, n )
- Xint v[], n;
- X
- X {
- X register int i, j, k;
- X
- X for ( i = n; i > 1; --i )
- X for ( j = 1; j < i; ++j )
- X if ( v[j] > v[j + 1] ) /* compare */
- X {
- X k = v[j]; /* exchange */
- X v[j] = v[j + 1];
- X v[j + 1] = k;
- X }
- X }
- X
- X
- X/* clower - replace upper-case letter to lower-case
- X *
- X * synopsis:
- X * Char clower();
- X * int c;
- X * c = clower( c );
- X */
- X
- XChar clower( c )
- Xregister int c;
- X
- X {
- X return ( (isascii( c ) && isupper( c )) ? tolower( c ) : c );
- X }
- X
- X
- X/* copy_string - returns a dynamically allocated copy of a string
- X *
- X * synopsis
- X * char *str, *copy, *copy_string();
- X * copy = copy_string( str );
- X */
- X
- Xchar *copy_string( str )
- Xregister char *str;
- X
- X {
- X register char *c;
- X char *copy;
- X
- X /* find length */
- X for ( c = str; *c; ++c )
- X ;
- X
- X copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) );
- X
- X if ( copy == NULL )
- X flexfatal( "dynamic memory failure in copy_string()" );
- X
- X for ( c = copy; (*c++ = *str++); )
- X ;
- X
- X return ( copy );
- X }
- X
- X
- X/* copy_unsigned_string -
- X * returns a dynamically allocated copy of a (potentially) unsigned string
- X *
- X * synopsis
- X * Char *str, *copy, *copy_unsigned_string();
- X * copy = copy_unsigned_string( str );
- X */
- X
- XChar *copy_unsigned_string( str )
- Xregister Char *str;
- X
- X {
- X register Char *c;
- X Char *copy;
- X
- X /* find length */
- X for ( c = str; *c; ++c )
- X ;
- X
- X copy = (Char *) malloc( (unsigned) ((c - str + 1) * sizeof( Char )) );
- X
- X if ( copy == NULL )
- X flexfatal( "dynamic memory failure in copy_unsigned_string()" );
- X
- X for ( c = copy; (*c++ = *str++); )
- X ;
- X
- X return ( copy );
- X }
- X
- X
- X/* cshell - shell sort a character array in increasing order
- X *
- X * synopsis
- X *
- X * Char v[n];
- X * int n, special_case_0;
- X * cshell( v, n, special_case_0 );
- X *
- X * description
- X * does a shell sort of the first n elements of array v.
- X * If special_case_0 is true, then any element equal to 0
- X * is instead assumed to have infinite weight.
- X *
- X * passed
- X * v - array to be sorted
- X * n - number of elements of v to be sorted
- X */
- X
- Xvoid cshell( v, n, special_case_0 )
- XChar v[];
- Xint n, special_case_0;
- X
- X {
- X int gap, i, j, jg;
- X Char k;
- X
- X for ( gap = n / 2; gap > 0; gap = gap / 2 )
- X for ( i = gap; i < n; ++i )
- X for ( j = i - gap; j >= 0; j = j - gap )
- X {
- X jg = j + gap;
- X
- X if ( special_case_0 )
- X {
- X if ( v[jg] == 0 )
- X break;
- X
- X else if ( v[j] != 0 && v[j] <= v[jg] )
- X break;
- X }
- X
- X else if ( v[j] <= v[jg] )
- X break;
- X
- X k = v[j];
- X v[j] = v[jg];
- X v[jg] = k;
- X }
- X }
- X
- X
- X/* dataend - finish up a block of data declarations
- X *
- X * synopsis
- X * dataend();
- X */
- X
- Xvoid dataend()
- X
- X {
- X if ( datapos > 0 )
- X dataflush();
- X
- X /* add terminator for initialization */
- X puts( " } ;\n" );
- X
- X dataline = 0;
- X datapos = 0;
- X }
- X
- X
- X
- X/* dataflush - flush generated data statements
- X *
- X * synopsis
- X * dataflush();
- X */
- X
- Xvoid dataflush()
- X
- X {
- X putchar( '\n' );
- X
- X if ( ++dataline >= NUMDATALINES )
- X {
- X /* put out a blank line so that the table is grouped into
- X * large blocks that enable the user to find elements easily
- X */
- X putchar( '\n' );
- X dataline = 0;
- X }
- X
- X /* reset the number of characters written on the current line */
- X datapos = 0;
- X }
- X
- X
- X/* flexerror - report an error message and terminate
- X *
- X * synopsis
- X * char msg[];
- X * flexerror( msg );
- X */
- X
- Xvoid flexerror( msg )
- Xchar msg[];
- X
- X {
- X fprintf( stderr, "%s: %s\n", program_name, msg );
- X
- X flexend( 1 );
- X }
- X
- X
- X/* flexfatal - report a fatal error message and terminate
- X *
- X * synopsis
- X * char msg[];
- X * flexfatal( msg );
- X */
- X
- Xvoid flexfatal( msg )
- Xchar msg[];
- X
- X {
- X fprintf( stderr, "%s: fatal internal error, %s\n", program_name, msg );
- X flexend( 1 );
- X }
- X
- X
- X/* flex_gettime - return current time
- X *
- X * synopsis
- X * char *flex_gettime(), *time_str;
- X * time_str = flex_gettime();
- X *
- X * note
- X * the routine name has the "flex_" prefix because of name clashes
- X * with Turbo-C
- X */
- X
- X/* include sys/types.h to use time_t and make lint happy */
- X
- X#ifndef MS_DOS
- X#ifndef VMS
- X#include <sys/types.h>
- X#else
- X#include <types.h>
- X#endif
- X#endif
- X
- X#ifdef MS_DOS
- X#include <time.h>
- Xtypedef long time_t;
- X#endif
- X
- X#ifdef AMIGA
- X#include <time.h>
- X#endif
- X
- Xchar *flex_gettime()
- X
- X {
- X time_t t, time();
- X char *result, *ctime(), *copy_string();
- X
- X t = time( (long *) 0 );
- X
- X result = copy_string( ctime( &t ) );
- X
- X /* get rid of trailing newline */
- X result[24] = '\0';
- X
- X return ( result );
- X }
- X
- X
- X/* lerrif - report an error message formatted with one integer argument
- X *
- X * synopsis
- X * char msg[];
- X * int arg;
- X * lerrif( msg, arg );
- X */
- X
- Xvoid lerrif( msg, arg )
- Xchar msg[];
- Xint arg;
- X
- X {
- X char errmsg[MAXLINE];
- X (void) sprintf( errmsg, msg, arg );
- X flexerror( errmsg );
- X }
- X
- X
- X/* lerrsf - report an error message formatted with one string argument
- X *
- X * synopsis
- X * char msg[], arg[];
- X * lerrsf( msg, arg );
- X */
- X
- Xvoid lerrsf( msg, arg )
- Xchar msg[], arg[];
- X
- X {
- X char errmsg[MAXLINE];
- X
- X (void) sprintf( errmsg, msg, arg );
- X flexerror( errmsg );
- X }
- X
- X
- X/* htoi - convert a hexadecimal digit string to an integer value
- X *
- X * synopsis:
- X * int val, htoi();
- X * Char str[];
- X * val = htoi( str );
- X */
- X
- Xint htoi( str )
- XChar str[];
- X
- X {
- X int result;
- X
- X (void) sscanf( (char *) str, "%x", &result );
- X
- X return ( result );
- X }
- X
- X
- X/* line_directive_out - spit out a "# line" statement */
- X
- Xvoid line_directive_out( output_file_name )
- XFILE *output_file_name;
- X
- X {
- X if ( infilename && gen_line_dirs )
- X fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename );
- X }
- X
- X
- X/* mk2data - generate a data statement for a two-dimensional array
- X *
- X * synopsis
- X * int value;
- X * mk2data( value );
- X *
- X * generates a data statement initializing the current 2-D array to "value"
- X */
- Xvoid mk2data( value )
- Xint value;
- X
- X {
- X if ( datapos >= NUMDATAITEMS )
- X {
- X putchar( ',' );
- X dataflush();
- X }
- X
- X if ( datapos == 0 )
- X /* indent */
- X fputs( " ", stdout );
- X
- X else
- X putchar( ',' );
- X
- X ++datapos;
- X
- X printf( "%5d", value );
- X }
- X
- X
- X/* mkdata - generate a data statement
- X *
- X * synopsis
- X * int value;
- X * mkdata( value );
- X *
- X * generates a data statement initializing the current array element to
- X * "value"
- X */
- Xvoid mkdata( value )
- Xint value;
- X
- X {
- X if ( datapos >= NUMDATAITEMS )
- X {
- X putchar( ',' );
- X dataflush();
- X }
- X
- X if ( datapos == 0 )
- X /* indent */
- X fputs( " ", stdout );
- X
- X else
- X putchar( ',' );
- X
- X ++datapos;
- X
- X printf( "%5d", value );
- X }
- X
- X
- X/* myctoi - return the integer represented by a string of digits
- X *
- X * synopsis
- X * Char array[];
- X * int val, myctoi();
- X * val = myctoi( array );
- X *
- X */
- X
- Xint myctoi( array )
- XChar array[];
- X
- X {
- X int val = 0;
- X
- X (void) sscanf( (char *) array, "%d", &val );
- X
- X return ( val );
- X }
- X
- X
- X/* myesc - return character corresponding to escape sequence
- X *
- X * synopsis
- X * Char array[], c, myesc();
- X * c = myesc( array );
- X *
- X */
- X
- XChar myesc( array )
- XChar array[];
- X
- X {
- X switch ( array[1] )
- X {
- X case 'a': return ( '\a' );
- X case 'b': return ( '\b' );
- X case 'f': return ( '\f' );
- X case 'n': return ( '\n' );
- X case 'r': return ( '\r' );
- X case 't': return ( '\t' );
- X case 'v': return ( '\v' );
- X
- X case 'x':
- X /* fall through */
- X
- X case '0':
- X case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X
- X { /* \<octal> or \x<hex> */
- X Char c, esc_char;
- X register int sptr = 1;
- X
- X if ( array[1] == 'x' )
- X ++sptr;
- X
- X while ( isascii( array[sptr] ) && isdigit( array[sptr] ) )
- X /* don't increment inside loop control because if
- X * isdigit() is a macro it will expand it to two
- X * increments ...
- X */
- X ++sptr;
- X
- X c = array[sptr];
- X array[sptr] = '\0';
- X
- X if ( array[1] == 'x' )
- X esc_char = htoi( array + 2 );
- X else
- X esc_char = otoi( array + 1 );
- X
- X array[sptr] = c;
- X
- X return ( esc_char );
- X }
- X
- X default:
- X return ( array[1] );
- X }
- X }
- X
- X
- X/* otoi - convert an octal digit string to an integer value
- X *
- X * synopsis:
- X * int val, otoi();
- X * Char str[];
- X * val = otoi( str );
- X */
- X
- Xint otoi( str )
- XChar str[];
- X
- X {
- X int result;
- X
- X (void) sscanf( (char *) str, "%o", &result );
- X
- X return ( result );
- X }
- X
- X
- X/* readable_form - return the the human-readable form of a character
- X *
- X * synopsis:
- X * int c;
- X * char *readable_form();
- X * <string> = readable_form( c );
- X *
- X * The returned string is in static storage.
- X */
- X
- Xchar *readable_form( c )
- Xregister int c;
- X
- X {
- X static char rform[10];
- X
- X if ( (c >= 0 && c < 32) || c >= 127 )
- X {
- X switch ( c )
- X {
- X case '\n': return ( "\\n" );
- X case '\t': return ( "\\t" );
- X case '\f': return ( "\\f" );
- X case '\r': return ( "\\r" );
- X case '\b': return ( "\\b" );
- X
- X default:
- X (void) sprintf( rform, "\\%.3o", c );
- X return ( rform );
- X }
- X }
- X
- X else if ( c == ' ' )
- X return ( "' '" );
- X
- X else
- X {
- X rform[0] = c;
- X rform[1] = '\0';
- X
- X return ( rform );
- X }
- X }
- X
- X
- X/* reallocate_array - increase the size of a dynamic array */
- X
- Xvoid *reallocate_array( array, size, element_size )
- Xvoid *array;
- Xint size, element_size;
- X
- X {
- X register void *new_array;
- X
- X /* same worry as in allocate_array(): */
- X if ( size * element_size <= 0 )
- X flexfatal( "attempt to increase array size by less than 1 byte" );
- X
- X new_array =
- X (void *) realloc( (char *)array, (unsigned) (size * element_size ));
- X
- X if ( new_array == NULL )
- X flexfatal( "attempt to increase array size failed" );
- X
- X return ( new_array );
- X }
- X
- X
- X/* skelout - write out one section of the skeleton file
- X *
- X * synopsis
- X * skelout();
- X *
- X * DESCRIPTION
- X * Copies from skelfile to stdout until a line beginning with "%%" or
- X * EOF is found.
- X */
- Xvoid skelout()
- X
- X {
- X char buf[MAXLINE];
- X
- X while ( fgets( buf, MAXLINE, skelfile ) != NULL )
- X if ( buf[0] == '%' && buf[1] == '%' )
- X break;
- X else
- X fputs( buf, stdout );
- X }
- X
- X
- X/* transition_struct_out - output a yy_trans_info structure
- X *
- X * synopsis
- X * int element_v, element_n;
- X * transition_struct_out( element_v, element_n );
- X *
- X * outputs the yy_trans_info structure with the two elements, element_v and
- X * element_n. Formats the output with spaces and carriage returns.
- X */
- X
- Xvoid transition_struct_out( element_v, element_n )
- Xint element_v, element_n;
- X
- X {
- X printf( "%7d, %5d,", element_v, element_n );
- X
- X datapos += TRANS_STRUCT_PRINT_LENGTH;
- X
- X if ( datapos >= 75 )
- X {
- X putchar( '\n' );
- X
- X if ( ++dataline % 10 == 0 )
- X putchar( '\n' );
- X
- X datapos = 0;
- X }
- X }
- END_OF_FILE
- if test 14248 -ne `wc -c <'misc.c'`; then
- echo shar: \"'misc.c'\" unpacked with wrong size!
- fi
- # end of 'misc.c'
- fi
- if test -f 'parse.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'parse.y'\"
- else
- echo shar: Extracting \"'parse.y'\" \(14546 characters\)
- sed "s/^X//" >'parse.y' <<'END_OF_FILE'
- X
- X/* parse.y - parser for flex input */
- X
- X%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP
- X
- X%{
- X/*-
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Vern Paxson.
- X *
- X * The United States Government has rights in this work pursuant
- X * to contract no. DE-AC03-76SF00098 between the United States
- X * Department of Energy and the University of California.
- X *
- X * Redistribution and use in source and binary forms are permitted provided
- X * that: (1) source distributions retain this entire copyright notice and
- X * comment, and (2) distributions including binaries display the following
- X * acknowledgement: ``This product includes software developed by the
- X * University of California, Berkeley and its contributors'' in the
- X * documentation or other materials provided with the distribution and in
- X * all advertising materials mentioning features or use of this software.
- X * Neither the name of the University nor the names of its contributors may
- X * be used to endorse or promote products derived from this software without
- X * specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xstatic char rcsid[] =
- X "@(#) $Header: WPL:Generators/flex-2.3/RCS/parse.y,v 1.2 90/07/15 01:16:53 loftus Exp $ (LBL)";
- X#endif
- X
- X#include "flexdef.h"
- X
- Xint pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
- Xint trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
- XChar clower();
- Xvoid build_eof_action();
- Xvoid yyerror( char * );
- X
- Xstatic int madeany = false; /* whether we've made the '.' character class */
- Xint previous_continued_action; /* whether the previous rule's action was '|' */
- X
- X%}
- X
- X%%
- Xgoal : initlex sect1 sect1end sect2 initforrule
- X { /* add default rule */
- X int def_rule;
- X
- X pat = cclinit();
- X cclnegate( pat );
- X
- X def_rule = mkstate( -pat );
- X
- X finish_rule( def_rule, false, 0, 0 );
- X
- X for ( i = 1; i <= lastsc; ++i )
- X scset[i] = mkbranch( scset[i], def_rule );
- X
- X if ( spprdflt )
- X fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )",
- X temp_action_file );
- X else
- X fputs( "ECHO", temp_action_file );
- X
- X fputs( ";\n\tYY_BREAK\n", temp_action_file );
- X }
- X ;
- X
- Xinitlex :
- X {
- X /* initialize for processing rules */
- X
- X /* create default DFA start condition */
- X scinstal( "INITIAL", false );
- X }
- X ;
- X
- Xsect1 : sect1 startconddecl WHITESPACE namelist1 '\n'
- X |
- X | error '\n'
- X { synerr( "unknown error processing section 1" ); }
- X ;
- X
- Xsect1end : SECTEND
- X ;
- X
- Xstartconddecl : SCDECL
- X {
- X /* these productions are separate from the s1object
- X * rule because the semantics must be done before
- X * we parse the remainder of an s1object
- X */
- X
- X xcluflg = false;
- X }
- X
- X | XSCDECL
- X { xcluflg = true; }
- X ;
- X
- Xnamelist1 : namelist1 WHITESPACE NAME
- X { scinstal( nmstr, xcluflg ); }
- X
- X | NAME
- X { scinstal( nmstr, xcluflg ); }
- X
- X | error
- X { synerr( "bad start condition list" ); }
- X ;
- X
- Xsect2 : sect2 initforrule flexrule '\n'
- X |
- X ;
- X
- Xinitforrule :
- X {
- X /* initialize for a parse of one rule */
- X trlcontxt = variable_trail_rule = varlength = false;
- X trailcnt = headcnt = rulelen = 0;
- X current_state_type = STATE_NORMAL;
- X previous_continued_action = continued_action;
- X new_rule();
- X }
- X ;
- X
- Xflexrule : scon '^' rule
- X {
- X pat = $3;
- X finish_rule( pat, variable_trail_rule,
- X headcnt, trailcnt );
- X
- X for ( i = 1; i <= actvp; ++i )
- X scbol[actvsc[i]] =
- X mkbranch( scbol[actvsc[i]], pat );
- X
- X if ( ! bol_needed )
- X {
- X bol_needed = true;
- X
- X if ( performance_report )
- X pinpoint_message(
- X "'^' operator results in sub-optimal performance" );
- X }
- X }
- X
- X | scon rule
- X {
- X pat = $2;
- X finish_rule( pat, variable_trail_rule,
- X headcnt, trailcnt );
- X
- X for ( i = 1; i <= actvp; ++i )
- X scset[actvsc[i]] =
- X mkbranch( scset[actvsc[i]], pat );
- X }
- X
- X | '^' rule
- X {
- X pat = $2;
- X finish_rule( pat, variable_trail_rule,
- X headcnt, trailcnt );
- X
- X /* add to all non-exclusive start conditions,
- X * including the default (0) start condition
- X */
- X
- X for ( i = 1; i <= lastsc; ++i )
- X if ( ! scxclu[i] )
- X scbol[i] = mkbranch( scbol[i], pat );
- X
- X if ( ! bol_needed )
- X {
- X bol_needed = true;
- X
- X if ( performance_report )
- X pinpoint_message(
- X "'^' operator results in sub-optimal performance" );
- X }
- X }
- X
- X | rule
- X {
- X pat = $1;
- X finish_rule( pat, variable_trail_rule,
- X headcnt, trailcnt );
- X
- X for ( i = 1; i <= lastsc; ++i )
- X if ( ! scxclu[i] )
- X scset[i] = mkbranch( scset[i], pat );
- X }
- X
- X | scon EOF_OP
- X { build_eof_action(); }
- X
- X | EOF_OP
- X {
- X /* this EOF applies to all start conditions
- X * which don't already have EOF actions
- X */
- X actvp = 0;
- X
- X for ( i = 1; i <= lastsc; ++i )
- X if ( ! sceof[i] )
- X actvsc[++actvp] = i;
- X
- X if ( actvp == 0 )
- X pinpoint_message(
- X "warning - all start conditions already have <<EOF>> rules" );
- X
- X else
- X build_eof_action();
- X }
- X
- X | error
- X { synerr( "unrecognized rule" ); }
- X ;
- X
- Xscon : '<' namelist2 '>'
- X ;
- X
- Xnamelist2 : namelist2 ',' NAME
- X {
- X if ( (scnum = sclookup( nmstr )) == 0 )
- X format_pinpoint_message(
- X "undeclared start condition %s", nmstr );
- X
- X else
- X actvsc[++actvp] = scnum;
- X }
- X
- X | NAME
- X {
- X if ( (scnum = sclookup( nmstr )) == 0 )
- X format_pinpoint_message(
- X "undeclared start condition %s", nmstr );
- X else
- X actvsc[actvp = 1] = scnum;
- X }
- X
- X | error
- X { synerr( "bad start condition list" ); }
- X ;
- X
- Xrule : re2 re
- X {
- X if ( transchar[lastst[$2]] != SYM_EPSILON )
- X /* provide final transition \now/ so it
- X * will be marked as a trailing context
- X * state
- X */
- X $2 = link_machines( $2, mkstate( SYM_EPSILON ) );
- X
- X mark_beginning_as_normal( $2 );
- X current_state_type = STATE_NORMAL;
- X
- X if ( previous_continued_action )
- X {
- X /* we need to treat this as variable trailing
- X * context so that the backup does not happen
- X * in the action but before the action switch
- X * statement. If the backup happens in the
- X * action, then the rules "falling into" this
- X * one's action will *also* do the backup,
- X * erroneously.
- X */
- X if ( ! varlength || headcnt != 0 )
- X {
- X fprintf( stderr,
- X "%s: warning - trailing context rule at line %d made variable because\n",
- X program_name, linenum );
- X fprintf( stderr,
- X " of preceding '|' action\n" );
- X }
- X
- X /* mark as variable */
- X varlength = true;
- X headcnt = 0;
- X }
- X
- X if ( varlength && headcnt == 0 )
- X { /* variable trailing context rule */
- X /* mark the first part of the rule as the accepting
- X * "head" part of a trailing context rule
- X */
- X /* by the way, we didn't do this at the beginning
- X * of this production because back then
- X * current_state_type was set up for a trail
- X * rule, and add_accept() can create a new
- X * state ...
- X */
- X add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK );
- X variable_trail_rule = true;
- X }
- X
- X else
- X trailcnt = rulelen;
- X
- X $$ = link_machines( $1, $2 );
- X }
- X
- X | re2 re '$'
- X { synerr( "trailing context used twice" ); }
- X
- X | re '$'
- X {
- X if ( trlcontxt )
- X {
- X synerr( "trailing context used twice" );
- X $$ = mkstate( SYM_EPSILON );
- X }
- X
- X else if ( previous_continued_action )
- X {
- X /* see the comment in the rule for "re2 re"
- X * above
- X */
- X if ( ! varlength || headcnt != 0 )
- X {
- X fprintf( stderr,
- X "%s: warning - trailing context rule at line %d made variable because\n",
- X program_name, linenum );
- X fprintf( stderr,
- X " of preceding '|' action\n" );
- X }
- X
- X /* mark as variable */
- X varlength = true;
- X headcnt = 0;
- X }
- X
- X trlcontxt = true;
- X
- X if ( ! varlength )
- X headcnt = rulelen;
- X
- X ++rulelen;
- X trailcnt = 1;
- X
- X eps = mkstate( SYM_EPSILON );
- X $$ = link_machines( $1,
- X link_machines( eps, mkstate( '\n' ) ) );
- X }
- X
- X | re
- X {
- X $$ = $1;
- X
- X if ( trlcontxt )
- X {
- X if ( varlength && headcnt == 0 )
- X /* both head and trail are variable-length */
- X variable_trail_rule = true;
- X else
- X trailcnt = rulelen;
- X }
- X }
- X ;
- X
- X
- Xre : re '|' series
- X {
- X varlength = true;
- X $$ = mkor( $1, $3 );
- X }
- X
- X | series
- X { $$ = $1; }
- X ;
- X
- X
- Xre2 : re '/'
- X {
- X /* this rule is written separately so
- X * the reduction will occur before the trailing
- X * series is parsed
- X */
- X
- X if ( trlcontxt )
- X synerr( "trailing context used twice" );
- X else
- X trlcontxt = true;
- X
- X if ( varlength )
- X /* we hope the trailing context is fixed-length */
- X varlength = false;
- X else
- X headcnt = rulelen;
- X
- X rulelen = 0;
- X
- X current_state_type = STATE_TRAILING_CONTEXT;
- X $$ = $1;
- X }
- X ;
- X
- Xseries : series singleton
- X {
- X /* this is where concatenation of adjacent patterns
- X * gets done
- X */
- X $$ = link_machines( $1, $2 );
- X }
- X
- X | singleton
- X { $$ = $1; }
- X ;
- X
- Xsingleton : singleton '*'
- X {
- X varlength = true;
- X
- X $$ = mkclos( $1 );
- X }
- X
- X | singleton '+'
- X {
- X varlength = true;
- X
- X $$ = mkposcl( $1 );
- X }
- X
- X | singleton '?'
- X {
- X varlength = true;
- X
- X $$ = mkopt( $1 );
- X }
- X
- X | singleton '{' NUMBER ',' NUMBER '}'
- X {
- X varlength = true;
- X
- X if ( $3 > $5 || $3 < 0 )
- X {
- X synerr( "bad iteration values" );
- X $$ = $1;
- X }
- X else
- X {
- X if ( $3 == 0 )
- X $$ = mkopt( mkrep( $1, $3, $5 ) );
- X else
- X $$ = mkrep( $1, $3, $5 );
- X }
- X }
- X
- X | singleton '{' NUMBER ',' '}'
- X {
- X varlength = true;
- X
- X if ( $3 <= 0 )
- X {
- X synerr( "iteration value must be positive" );
- X $$ = $1;
- X }
- X
- X else
- X $$ = mkrep( $1, $3, INFINITY );
- X }
- X
- X | singleton '{' NUMBER '}'
- X {
- X /* the singleton could be something like "(foo)",
- X * in which case we have no idea what its length
- X * is, so we punt here.
- X */
- X varlength = true;
- X
- X if ( $3 <= 0 )
- X {
- X synerr( "iteration value must be positive" );
- X $$ = $1;
- X }
- X
- X else
- X $$ = link_machines( $1, copysingl( $1, $3 - 1 ) );
- X }
- X
- X | '.'
- X {
- X if ( ! madeany )
- X {
- X /* create the '.' character class */
- X anyccl = cclinit();
- X ccladd( anyccl, '\n' );
- X cclnegate( anyccl );
- X
- X if ( useecs )
- X mkeccl( ccltbl + cclmap[anyccl],
- X ccllen[anyccl], nextecm,
- X ecgroup, csize, csize );
- X
- X madeany = true;
- X }
- X
- X ++rulelen;
- X
- X $$ = mkstate( -anyccl );
- X }
- X
- X | fullccl
- X {
- X if ( ! cclsorted )
- X /* sort characters for fast searching. We use a
- X * shell sort since this list could be large.
- X */
- X cshell( ccltbl + cclmap[$1], ccllen[$1], true );
- X
- X if ( useecs )
- X mkeccl( ccltbl + cclmap[$1], ccllen[$1],
- X nextecm, ecgroup, csize, csize );
- X
- X ++rulelen;
- X
- X $$ = mkstate( -$1 );
- X }
- X
- X | PREVCCL
- X {
- X ++rulelen;
- X
- X $$ = mkstate( -$1 );
- X }
- X
- X | '"' string '"'
- X { $$ = $2; }
- X
- X | '(' re ')'
- X { $$ = $2; }
- X
- X | CHAR
- X {
- X ++rulelen;
- X
- X if ( caseins && $1 >= 'A' && $1 <= 'Z' )
- X $1 = clower( $1 );
- X
- X $$ = mkstate( $1 );
- X }
- X ;
- X
- Xfullccl : '[' ccl ']'
- X { $$ = $2; }
- X
- X | '[' '^' ccl ']'
- X {
- X /* *Sigh* - to be compatible Unix lex, negated ccls
- X * match newlines
- X */
- X#ifdef NOTDEF
- X ccladd( $3, '\n' ); /* negated ccls don't match '\n' */
- X cclsorted = false; /* because we added the newline */
- X#endif
- X cclnegate( $3 );
- X $$ = $3;
- X }
- X ;
- X
- Xccl : ccl CHAR '-' CHAR
- X {
- X if ( $2 > $4 )
- X synerr( "negative range in character class" );
- X
- X else
- X {
- X if ( caseins )
- X {
- X if ( $2 >= 'A' && $2 <= 'Z' )
- X $2 = clower( $2 );
- X if ( $4 >= 'A' && $4 <= 'Z' )
- X $4 = clower( $4 );
- X }
- X
- X for ( i = $2; i <= $4; ++i )
- X ccladd( $1, i );
- X
- X /* keep track if this ccl is staying in alphabetical
- X * order
- X */
- X cclsorted = cclsorted && ($2 > lastchar);
- X lastchar = $4;
- X }
- X
- X $$ = $1;
- X }
- X
- X | ccl CHAR
- X {
- X if ( caseins )
- X if ( $2 >= 'A' && $2 <= 'Z' )
- X $2 = clower( $2 );
- X
- X ccladd( $1, $2 );
- X cclsorted = cclsorted && ($2 > lastchar);
- X lastchar = $2;
- X $$ = $1;
- X }
- X
- X |
- X {
- X cclsorted = true;
- X lastchar = 0;
- X $$ = cclinit();
- X }
- X ;
- X
- Xstring : string CHAR
- X {
- X if ( caseins )
- X if ( $2 >= 'A' && $2 <= 'Z' )
- X $2 = clower( $2 );
- X
- X ++rulelen;
- X
- X $$ = link_machines( $1, mkstate( $2 ) );
- X }
- X
- X |
- X { $$ = mkstate( SYM_EPSILON ); }
- X ;
- X
- X%%
- X
- X
- X/* build_eof_action - build the "<<EOF>>" action for the active start
- X * conditions
- X */
- X
- Xvoid build_eof_action()
- X
- X {
- X register int i;
- X
- X for ( i = 1; i <= actvp; ++i )
- X {
- X if ( sceof[actvsc[i]] )
- X format_pinpoint_message(
- X "multiple <<EOF>> rules for start condition %s",
- X scname[actvsc[i]] );
- X
- X else
- X {
- X sceof[actvsc[i]] = true;
- X fprintf( temp_action_file, "case YY_STATE_EOF(%s):\n",
- X scname[actvsc[i]] );
- X }
- X }
- X
- X line_directive_out( temp_action_file );
- X }
- X
- X
- X/* synerr - report a syntax error */
- X
- Xvoid synerr( str )
- Xchar str[];
- X
- X {
- X syntaxerror = true;
- X pinpoint_message( str );
- X }
- X
- X
- X/* format_pinpoint_message - write out a message formatted with one string,
- X * pinpointing its location
- X */
- X
- Xvoid format_pinpoint_message( msg, arg )
- Xchar msg[], arg[];
- X
- X {
- X char errmsg[MAXLINE];
- X
- X (void) sprintf( errmsg, msg, arg );
- X pinpoint_message( errmsg );
- X }
- X
- X
- X/* pinpoint_message - write out a message, pinpointing its location */
- X
- Xvoid pinpoint_message( str )
- Xchar str[];
- X
- X {
- X fprintf( stderr, "\"%s\", line %d: %s\n", infilename, linenum, str );
- X }
- X
- X
- X/* yyerror - eat up an error message from the parser;
- X * currently, messages are ignore
- X */
- X
- Xvoid yyerror( msg )
- Xchar msg[];
- X
- X {
- X }
- END_OF_FILE
- if test 14546 -ne `wc -c <'parse.y'`; then
- echo shar: \"'parse.y'\" unpacked with wrong size!
- fi
- # end of 'parse.y'
- fi
- if test -f 'scan.l' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'scan.l'\"
- else
- echo shar: Extracting \"'scan.l'\" \(12444 characters\)
- sed "s/^X//" >'scan.l' <<'END_OF_FILE'
- X
- X/* scan.l - scanner for flex input */
- X
- X%{
- X/*-
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Vern Paxson.
- X *
- X * The United States Government has rights in this work pursuant
- X * to contract no. DE-AC03-76SF00098 between the United States
- X * Department of Energy and the University of California.
- X *
- X * Redistribution and use in source and binary forms are permitted provided
- X * that: (1) source distributions retain this entire copyright notice and
- X * comment, and (2) distributions including binaries display the following
- X * acknowledgement: ``This product includes software developed by the
- X * University of California, Berkeley and its contributors'' in the
- X * documentation or other materials provided with the distribution and in
- X * all advertising materials mentioning features or use of this software.
- X * Neither the name of the University nor the names of its contributors may
- X * be used to endorse or promote products derived from this software without
- X * specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xstatic char rcsid[] =
- X "@(#) $Header: WPL:Generators/flex-2.3/RCS/scan.l,v 1.2 90/07/15 01:16:31 loftus Exp $ (LBL)";
- X#endif
- X
- X#undef yywrap
- X
- X#include "flexdef.h"
- X#include "parse.h"
- X
- X#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext )
- X#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" );
- X
- X#undef YY_DECL
- X#define YY_DECL \
- X int flexscan()
- X
- X#define RETURNCHAR \
- X yylval = yytext[0]; \
- X return ( CHAR );
- X
- X#define RETURNNAME \
- X (void) strcpy( nmstr, (char *) yytext ); \
- X return ( NAME );
- X
- X#define PUT_BACK_STRING(str, start) \
- X for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \
- X unput((str)[i])
- X
- X#define CHECK_REJECT(str) \
- X if ( all_upper( str ) ) \
- X reject = true;
- X
- X#define CHECK_YYMORE(str) \
- X if ( all_lower( str ) ) \
- X yymore_used = true;
- X%}
- X
- X%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
- X%x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT
- X%x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2 XLATION
- X
- XWS [ \t\f]+
- XOPTWS [ \t\f]*
- XNOT_WS [^ \t\f\n]
- X
- XNAME [a-z_][a-z_0-9-]*
- XNOT_NAME [^a-z_\n]+
- X
- XSCNAME {NAME}
- X
- XESCSEQ \\([^\n]|[0-9]{1,3}|x[0-9a-f]{1,2})
- X
- X%%
- X static int bracelevel, didadef;
- X int i, indented_code, checking_used, new_xlation;
- X int doing_codeblock = false;
- X Char nmdef[MAXLINE], myesc();
- X
- X^{WS} indented_code = true; BEGIN(CODEBLOCK);
- X^#.*\n ++linenum; /* treat as a comment */
- X^"/*" ECHO; BEGIN(C_COMMENT);
- X^"%s"{NAME}? return ( SCDECL );
- X^"%x"{NAME}? return ( XSCDECL );
- X^"%{".*\n {
- X ++linenum;
- X line_directive_out( stdout );
- X indented_code = false;
- X BEGIN(CODEBLOCK);
- X }
- X
- X{WS} return ( WHITESPACE );
- X
- X^"%%".* {
- X sectnum = 2;
- X line_directive_out( stdout );
- X BEGIN(SECT2PROLOG);
- X return ( SECTEND );
- X }
- X
- X^"%used" {
- X pinpoint_message( "warning - %%used/%%unused have been deprecated" );
- X checking_used = REALLY_USED; BEGIN(USED_LIST);
- X }
- X^"%unused" {
- X checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
- X pinpoint_message( "warning - %%used/%%unused have been deprecated" );
- X checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
- X }
- X
- X
- X^"%"[aeknopt]" ".*\n {
- X#ifdef NOTDEF
- X fprintf( stderr,
- X "old-style lex command at line %d ignored:\n\t%s",
- X linenum, yytext );
- X#endif
- X ++linenum;
- X }
- X
- X^"%"[cr]{OPTWS} /* ignore old lex directive */
- X
- X%t{OPTWS}\n {
- X ++linenum;
- X xlation =
- X (int *) malloc( sizeof( int ) * (unsigned) csize );
- X
- X if ( ! xlation )
- X flexfatal(
- X "dynamic memory failure building %t table" );
- X
- X for ( i = 0; i < csize; ++i )
- X xlation[i] = 0;
- X
- X num_xlations = 0;
- X
- X BEGIN(XLATION);
- X }
- X
- X^"%"[^sxanpekotcru{}]{OPTWS} synerr( "unrecognized '%' directive" );
- X
- X^{NAME} {
- X (void) strcpy( nmstr, (char *) yytext );
- X didadef = false;
- X BEGIN(PICKUPDEF);
- X }
- X
- X{SCNAME} RETURNNAME;
- X^{OPTWS}\n ++linenum; /* allows blank lines in section 1 */
- X{OPTWS}\n ++linenum; return ( '\n' );
- X. synerr( "illegal character" ); BEGIN(RECOVER);
- X
- X
- X<C_COMMENT>"*/" ECHO; BEGIN(INITIAL);
- X<C_COMMENT>"*/".*\n ++linenum; ECHO; BEGIN(INITIAL);
- X<C_COMMENT>[^*\n]+ ECHO;
- X<C_COMMENT>"*" ECHO;
- X<C_COMMENT>\n ++linenum; ECHO;
- X
- X
- X<CODEBLOCK>^"%}".*\n ++linenum; BEGIN(INITIAL);
- X<CODEBLOCK>"reject" ECHO; CHECK_REJECT(yytext);
- X<CODEBLOCK>"yymore" ECHO; CHECK_YYMORE(yytext);
- X<CODEBLOCK>{NAME}|{NOT_NAME}|. ECHO;
- X<CODEBLOCK>\n {
- X ++linenum;
- X ECHO;
- X if ( indented_code )
- X BEGIN(INITIAL);
- X }
- X
- X
- X<PICKUPDEF>{WS} /* separates name and definition */
- X
- X<PICKUPDEF>{NOT_WS}.* {
- X (void) strcpy( (char *) nmdef, (char *) yytext );
- X
- X for ( i = strlen( (char *) nmdef ) - 1;
- X i >= 0 &&
- X nmdef[i] == ' ' || nmdef[i] == '\t';
- X --i )
- X ;
- X
- X nmdef[i + 1] = '\0';
- X
- X ndinstal( nmstr, nmdef );
- X didadef = true;
- X }
- X
- X<PICKUPDEF>\n {
- X if ( ! didadef )
- X synerr( "incomplete name definition" );
- X BEGIN(INITIAL);
- X ++linenum;
- X }
- X
- X<RECOVER>.*\n ++linenum; BEGIN(INITIAL); RETURNNAME;
- X
- X
- X<USED_LIST>\n ++linenum; BEGIN(INITIAL);
- X<USED_LIST>{WS}
- X<USED_LIST>"reject" {
- X if ( all_upper( yytext ) )
- X reject_really_used = checking_used;
- X else
- X synerr( "unrecognized %used/%unused construct" );
- X }
- X<USED_LIST>"yymore" {
- X if ( all_lower( yytext ) )
- X yymore_really_used = checking_used;
- X else
- X synerr( "unrecognized %used/%unused construct" );
- X }
- X<USED_LIST>{NOT_WS}+ synerr( "unrecognized %used/%unused construct" );
- X
- X
- X<XLATION>"%t"{OPTWS}\n ++linenum; BEGIN(INITIAL);
- X<XLATION>^{OPTWS}[0-9]+ ++num_xlations; new_xlation = true;
- X<XLATION>^. synerr( "bad row in translation table" );
- X<XLATION>{WS} /* ignore whitespace */
- X
- X<XLATION>{ESCSEQ} {
- X xlation[myesc( yytext )] =
- X (new_xlation ? num_xlations : -num_xlations);
- X new_xlation = false;
- X }
- X<XLATION>. {
- X xlation[yytext[0]] =
- X (new_xlation ? num_xlations : -num_xlations);
- X new_xlation = false;
- X }
- X
- X<XLATION>\n ++linenum;
- X
- X
- X<SECT2PROLOG>.*\n/{NOT_WS} {
- X ++linenum;
- X ACTION_ECHO;
- X MARK_END_OF_PROLOG;
- X BEGIN(SECT2);
- X }
- X
- X<SECT2PROLOG>.*\n ++linenum; ACTION_ECHO;
- X
- X<SECT2PROLOG><<EOF>> MARK_END_OF_PROLOG; yyterminate();
- X
- X<SECT2>^{OPTWS}\n ++linenum; /* allow blank lines in section 2 */
- X
- X<SECT2>^({WS}|"%{") {
- X indented_code = (yytext[0] != '%');
- X doing_codeblock = true;
- X bracelevel = 1;
- X
- X if ( indented_code )
- X ACTION_ECHO;
- X
- X BEGIN(CODEBLOCK_2);
- X }
- X
- X<SECT2>"<" BEGIN(SC); return ( '<' );
- X<SECT2>^"^" return ( '^' );
- X<SECT2>\" BEGIN(QUOTE); return ( '"' );
- X<SECT2>"{"/[0-9] BEGIN(NUM); return ( '{' );
- X<SECT2>"{"[^0-9\n][^}\n]* BEGIN(BRACEERROR);
- X<SECT2>"$"/[ \t\n] return ( '$' );
- X
- X<SECT2>{WS}"%{" {
- X bracelevel = 1;
- X BEGIN(PERCENT_BRACE_ACTION);
- X return ( '\n' );
- X }
- X<SECT2>{WS}"|".*\n continued_action = true; ++linenum; return ( '\n' );
- X
- X<SECT2>{WS} {
- X /* this rule is separate from the one below because
- X * otherwise we get variable trailing context, so
- X * we can't build the scanner using -{f,F}
- X */
- X bracelevel = 0;
- X continued_action = false;
- X BEGIN(ACTION);
- X return ( '\n' );
- X }
- X
- X<SECT2>{OPTWS}/\n {
- X bracelevel = 0;
- X continued_action = false;
- X BEGIN(ACTION);
- X return ( '\n' );
- X }
- X
- X<SECT2>^{OPTWS}\n ++linenum; return ( '\n' );
- X
- X<SECT2>"<<EOF>>" return ( EOF_OP );
- X
- X<SECT2>^"%%".* {
- X sectnum = 3;
- X BEGIN(SECT3);
- X return ( EOF ); /* to stop the parser */
- X }
- X
- X<SECT2>"["([^\\\]\n]|{ESCSEQ})+"]" {
- X int cclval;
- X
- X (void) strcpy( nmstr, (char *) yytext );
- X
- X /* check to see if we've already encountered this ccl */
- X if ( (cclval = ccllookup( (Char *) nmstr )) )
- X {
- X yylval = cclval;
- X ++cclreuse;
- X return ( PREVCCL );
- X }
- X else
- X {
- X /* we fudge a bit. We know that this ccl will
- X * soon be numbered as lastccl + 1 by cclinit
- X */
- X cclinstal( (Char *) nmstr, lastccl + 1 );
- X
- X /* push back everything but the leading bracket
- X * so the ccl can be rescanned
- X */
- X PUT_BACK_STRING((Char *) nmstr, 1);
- X
- X BEGIN(FIRSTCCL);
- X return ( '[' );
- X }
- X }
- X
- X<SECT2>"{"{NAME}"}" {
- X register Char *nmdefptr;
- X Char *ndlookup();
- X
- X (void) strcpy( nmstr, (char *) yytext );
- X nmstr[yyleng - 1] = '\0'; /* chop trailing brace */
- X
- X /* lookup from "nmstr + 1" to chop leading brace */
- X if ( ! (nmdefptr = ndlookup( nmstr + 1 )) )
- X synerr( "undefined {name}" );
- X
- X else
- X { /* push back name surrounded by ()'s */
- X unput(')');
- X PUT_BACK_STRING(nmdefptr, 0);
- X unput('(');
- X }
- X }
- X
- X<SECT2>[/|*+?.()] return ( (int) yytext[0] );
- X<SECT2>. RETURNCHAR;
- X<SECT2>\n ++linenum; return ( '\n' );
- X
- X
- X<SC>"," return ( ',' );
- X<SC>">" BEGIN(SECT2); return ( '>' );
- X<SC>">"/"^" BEGIN(CARETISBOL); return ( '>' );
- X<SC>{SCNAME} RETURNNAME;
- X<SC>. synerr( "bad start condition name" );
- X
- X<CARETISBOL>"^" BEGIN(SECT2); return ( '^' );
- X
- X
- X<QUOTE>[^"\n] RETURNCHAR;
- X<QUOTE>\" BEGIN(SECT2); return ( '"' );
- X
- X<QUOTE>\n {
- X synerr( "missing quote" );
- X BEGIN(SECT2);
- X ++linenum;
- X return ( '"' );
- X }
- X
- X
- X<FIRSTCCL>"^"/[^-\n] BEGIN(CCL); return ( '^' );
- X<FIRSTCCL>"^"/- return ( '^' );
- X<FIRSTCCL>- BEGIN(CCL); yylval = '-'; return ( CHAR );
- X<FIRSTCCL>. BEGIN(CCL); RETURNCHAR;
- X
- X<CCL>-/[^\]\n] return ( '-' );
- X<CCL>[^\]\n] RETURNCHAR;
- X<CCL>"]" BEGIN(SECT2); return ( ']' );
- X
- X
- X<NUM>[0-9]+ {
- X yylval = myctoi( yytext );
- X return ( NUMBER );
- X }
- X
- X<NUM>"," return ( ',' );
- X<NUM>"}" BEGIN(SECT2); return ( '}' );
- X
- X<NUM>. {
- X synerr( "bad character inside {}'s" );
- X BEGIN(SECT2);
- X return ( '}' );
- X }
- X
- X<NUM>\n {
- X synerr( "missing }" );
- X BEGIN(SECT2);
- X ++linenum;
- X return ( '}' );
- X }
- X
- X
- X<BRACEERROR>"}" synerr( "bad name in {}'s" ); BEGIN(SECT2);
- X<BRACEERROR>\n synerr( "missing }" ); ++linenum; BEGIN(SECT2);
- X
- X
- X<PERCENT_BRACE_ACTION,CODEBLOCK_2>{OPTWS}"%}".* bracelevel = 0;
- X<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"reject" {
- X ACTION_ECHO;
- X CHECK_REJECT(yytext);
- X }
- X<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"yymore" {
- X ACTION_ECHO;
- X CHECK_YYMORE(yytext);
- X }
- X<PERCENT_BRACE_ACTION,CODEBLOCK_2>{NAME}|{NOT_NAME}|. ACTION_ECHO;
- X<PERCENT_BRACE_ACTION,CODEBLOCK_2>\n {
- X ++linenum;
- X ACTION_ECHO;
- X if ( bracelevel == 0 ||
- X (doing_codeblock && indented_code) )
- X {
- X if ( ! doing_codeblock )
- X fputs( "\tYY_BREAK\n", temp_action_file );
- X
- X doing_codeblock = false;
- X BEGIN(SECT2);
- X }
- X }
- X
- X
- X /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
- X<ACTION>"{" ACTION_ECHO; ++bracelevel;
- X<ACTION>"}" ACTION_ECHO; --bracelevel;
- X<ACTION>[^a-z_{}"'/\n]+ ACTION_ECHO;
- X<ACTION>{NAME} ACTION_ECHO;
- X<ACTION>"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT);
- X<ACTION>"'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
- X<ACTION>\" ACTION_ECHO; BEGIN(ACTION_STRING);
- X<ACTION>\n {
- X ++linenum;
- X ACTION_ECHO;
- X if ( bracelevel == 0 )
- X {
- X fputs( "\tYY_BREAK\n", temp_action_file );
- X BEGIN(SECT2);
- X }
- X }
- X<ACTION>. ACTION_ECHO;
- X
- X<ACTION_COMMENT>"*/" ACTION_ECHO; BEGIN(ACTION);
- X<ACTION_COMMENT>[^*\n]+ ACTION_ECHO;
- X<ACTION_COMMENT>"*" ACTION_ECHO;
- X<ACTION_COMMENT>\n ++linenum; ACTION_ECHO;
- X<ACTION_COMMENT>. ACTION_ECHO;
- X
- X<ACTION_STRING>[^"\\\n]+ ACTION_ECHO;
- X<ACTION_STRING>\\. ACTION_ECHO;
- X<ACTION_STRING>\n ++linenum; ACTION_ECHO;
- X<ACTION_STRING>\" ACTION_ECHO; BEGIN(ACTION);
- X<ACTION_STRING>. ACTION_ECHO;
- X
- X<ACTION,ACTION_COMMENT,ACTION_STRING><<EOF>> {
- X synerr( "EOF encountered inside an action" );
- X yyterminate();
- X }
- X
- X
- X<SECT2,QUOTE,CCL>{ESCSEQ} {
- X yylval = myesc( yytext );
- X return ( CHAR );
- X }
- X
- X<FIRSTCCL>{ESCSEQ} {
- X yylval = myesc( yytext );
- X BEGIN(CCL);
- X return ( CHAR );
- X }
- X
- X
- X<SECT3>.*(\n?) ECHO;
- X%%
- X
- X
- Xint yywrap()
- X
- X {
- X if ( --num_input_files > 0 )
- X {
- X set_input_file( *++input_files );
- X return ( 0 );
- X }
- X
- X else
- X return ( 1 );
- X }
- X
- X
- X/* set_input_file - open the given file (if NULL, stdin) for scanning */
- X
- Xvoid set_input_file( file )
- Xchar *file;
- X
- X {
- X if ( file )
- X {
- X infilename = file;
- X yyin = fopen( infilename, "r" );
- X
- X if ( yyin == NULL )
- X lerrsf( "can't open %s", file );
- X }
- X
- X else
- X {
- X yyin = stdin;
- X infilename = "<stdin>";
- X }
- X }
- END_OF_FILE
- if test 12444 -ne `wc -c <'scan.l'`; then
- echo shar: \"'scan.l'\" unpacked with wrong size!
- fi
- # end of 'scan.l'
- fi
- echo shar: End of archive 2 \(of 13\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 13 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-